<?php
/**
 * 无限的等级树
 * @author Administrator
 */
/*
$list = array(
        	array('id'=>1,'name'=>'食品','parent'=>0),
        	array('id'=>2,'name'=>'水果','parent'=>1),
        	array('id'=>3,'name'=>'蔬菜','parent'=>1),
        	array('id'=>4,'name'=>'桃子','parent'=>2),
        	array('id'=>5,'name'=>'西瓜','parent'=>2),
        	array('id'=>6,'name'=>'香蕉','parent'=>2),
        	array('id'=>7,'name'=>'芹菜','parent'=>3),
        	array('id'=>8,'name'=>'白菜','parent'=>3),
        	array('id'=>9,'name'=>'青菜','parent'=>3),
        	array('id'=>10,'name'=>'萝卜','parent'=>3),
        	array('id'=>11,'name'=>'牛肉','parent'=>15),
        	array('id'=>12,'name'=>'羊肉','parent'=>15),
        	array('id'=>13,'name'=>'猪肉','parent'=>15),
        	array('id'=>15,'name'=>'肉类','parent'=>1),
        );
        $tree = new inf_node('root');
        shuffle($list);
        foreach($list as $obj)
        {
        	$tnode = new inf_node($obj['name'],$obj['id'],$obj['parent']);
        	$pnode = $tree->getNodeById($obj['parent']);
        	if($pnode!=false)
        	{
        		$pnode->addChild($tnode);
        	}
        	else
        	{
        		$tree->addChild($tnode);
        	}
        }
        $body = $tree->view();
        $tree->flush();
        $body .= $tree->view();
 */
class Tree {
	/**
	 *  索引 递归增长
	 * @var int
	 */
	private $m_index;
	private $m_children;
	
	public $id;
	public $pid;
	public $level;
	public $parent;
	public $name;
	
	public function __construct($name, $id = 0, $pid = 0) {
		$this->id = $id;
		$this->pid = $pid;
		$this->level = 0;
		$this->name = $name;
		$this->m_children = array ();
	}
	
	/**
	 * 设置索引号
	 * @param $index int
	 */
	protected function setIndex($index) {
		$this->m_index = $index;
	}
	/**
	 * 获取索引号
	 */
	protected function getIndex() {
		return $this->m_index;
	}
	/**
	 * 添加子节点
	 * @param $node inf_node
	 */
	public function addChild($node) {
		if ($this->m_children !== null) {
			$node->setIndex ( count ( $this->m_children ) );
			array_push ( $this->m_children, $node );
			$node->parent = $this;
			$node->setLevel ( $this->level + 1 );
		}
	}
	
	/**
	 * 设置某一个节点
	 * @param $node inf_node
	 * @param $index int
	 */
	public function setChildAt($node, $index) {
		$index = $this->removeChild ( $node );
		if ($index !== false) {
			if ($node->getIndex () < $index) {
				$this->addChildAt ( $node, $index - 1 );
			} else {
				$this->addChildAt ( $node, $index );
			}
		}
		return $index;
	}
	
	/**
	 * 插入node到特定位置
	 * @param $node inf_node
	 * @param $index int 如果index 超出范围，自动自增到最大。
	 */
	public function addChildAt($node, $index) {
		if ($this->m_children !== null) {
			$is_insert = false;
			if ($index < 0)
				$index = count ( $this->m_children ) + $index;
			
			$pre_childs = array_slice ( $this->m_children, 0, $index );
			$suffix_childs = array_slice ( $this->m_children, $index, count ( $this->m_children ) - $index );
			
			if (count ( $suffix_childs ) > 0) {
				$node->setIndex ( $index );
				foreach ( $suffix_childs as $n ) {
					$n->setIndex ( $n->getIndex () + 1 );
				}
				$this->m_children = array_merge ( $pre_childs, array (
					
					$node 
				), $suffix_childs );
			} else {
				$this->addChild ( $node );
				return;
			}
			$node->parent = $this;
			$node->setLevel ( $this->level + 1 );
		}
	}
	
	/**
	 * 删除当前节点
	 * @param $node inf_node
	 */
	public function removeChild($node) {
		$index = array_search ( $node, $this->m_children );
		if ($index !== false) {
			$this->removeChildAt ( $index );
		}
		return $index;
	}
	
	/**
	 * 删除当前节点下第index个子节点。
	 * @param $index int
	 */
	public function removeChildAt($index) {
		$pre_childs = array_slice ( $this->m_children, 0, $index );
		$suffix_childs = array_slice ( $this->m_children, $index + 1, count ( $this->m_children ) - $index - 1 );
		if (count ( $suffix_childs ) > 0) {
			foreach ( $suffix_childs as $node ) {
				$node->setIndex ( $node->getIndex () - 1 );
			}
		}
		array_splice ( $this->m_children, $index, 1 );
		
		return $this->m_children;
	}
	
	/**
	 * 设置当前节点以及其子节点的所有目录级别
	 * @param $level int
	 */
	public function setLevel($level) {
		$has_child = true;
		$this->level = $level;
		while ( $has_child ) {
			$has_child = false;
			if (count ( $this->m_children ) > 0) {
				foreach ( $this->m_children as $node ) {
					$t_has_child = $node->setLevel ( $level + 1 );
					if ($t_has_child) {
						$has_child = true;
					}
				}
			}
		}
		return $has_child;
	}
	/**
	 * 通过id获得节点
	 * @param $id int
	 */
	public function getNodeById($id) {
		if ($this->id == $id) {
			return $this;
		}
		$is_find = false;
		if (count ( $this->m_children ) > 0) {
			foreach ( $this->m_children as $node ) {
				$is_find = $node->getNodeById ( $id );
				if ($is_find != false)
					break;
			}
		}
		return $is_find;
	}
	
	/**
	 * 刷新树
	 */
	public function flush() {
		if (count ( $this->m_children ) > 0) {
			foreach ( $this->m_children as $node ) {
				$pnode = $this->getNodeById ( $node->pid );
				if ($pnode == $node) {
					continue;
				}
				if ($pnode != false) {
					$this->removeChild ( $node );
					$pnode->addChild ( $node );
				}
				$node->flush ();
			}
		}
	}
	
	/**
	 * 测试输出
	 */
	public function view() {
		$view = '';
		if (count ( $this->m_children ) > 0) {
			foreach ( $this->m_children as $node ) {
				$view .= $node;
				$view .= $node->view ();
			}
		}
		return $view;
	}
	
	public function __toString() {
		return "id:".$this->id.";name:".$this->name.";pid:".$this->pid."<br>";
		//return '<li>' . $this->level . '.' . $this->getIndex () . '   ' . $this->name . ' id:' . $this->id . ' pid:' . $this->pid . '</li>';
	}
}